﻿using Koala.Pro.Common;
using Koala.Pro.Common.Extension;
using Koala.Pro.Core.Dto;
using Koala.Pro.Core.Models;
using Koala.Pro.Services;
using Nito.AsyncEx;
using System.Reflection;

namespace Koala.Pro.Helpers
{
    internal class SecurityHelper
    {
        private static bool InUserList(List<UserInfo> list, UserInfo userInfo)
        {
            bool result = false;
            if (list != null && list.Count > 0)
            {
                result = list.Any((UserInfo s) => s.Id == userInfo.Id);
            }
            return result;
        }

        public static async Task<List<UserInfo>> GetUsersByDict(Dictionary<string, string> dict)
        {
            List<UserInfo> list = new List<UserInfo>();
            foreach (string key in dict.Keys)
            {
                if (key.IndexOf(':') > 0)
                {
                    string[] array = key.Split(':');
                    string text = array[0].ToLower();
                    string str = array[1];
                    switch (text)
                    {
                        case "roleid":
                            foreach (UserInfo item in await BLLFactory<IUserService>.Instance.GetUsersByRole(str.ToInt32()))
                            {
                                if (!InUserList(list, item))
                                {
                                    list.Add(item);
                                }
                            }
                            break;
                        case "deptid":
                            foreach (UserInfo item2 in await BLLFactory<IUserService>.Instance.FindByDept(str.ToInt32()))
                            {
                                if (!InUserList(list, item2))
                                {
                                    list.Add(item2);
                                }
                            }
                            break;
                        case "userid":
                            {
                                UserInfo userInfo = await BLLFactory<IUserService>.Instance.GetAsync(str.ToInt32());
                                if (userInfo != null && !InUserList(list, userInfo))
                                {
                                    list.Add(userInfo);
                                }
                                break;
                            }
                    }
                }
                else
                {
                    UserInfo userInfo2 = await BLLFactory<IUserService>.Instance.GetAsync(key.ToInt32());
                    if (userInfo2 != null)
                    {
                        list.Add(userInfo2);
                    }
                }
            }
            return list;
        }

        public static async Task<List<UserInfo>> GetUsersByJson(string json)
        {
            List<UserInfo> list = new List<UserInfo>();
            if (!string.IsNullOrEmpty(json))
            {
                Dictionary<string, string> dictionary = json.ToDictObject();
                if (dictionary != null)
                {
                    List<UserInfo> list2 = await GetUsersByDict(dictionary);
                    if (list2 != null)
                    {
                        list.AddRange(list2);
                    }
                }
                else
                {
                    int result = 0;
                    if (int.TryParse(json, out result))
                    {
                        UserInfo userInfo = await BLLFactory<IUserService>.Instance.GetAsync(result);
                        if (userInfo != null && !InUserList(list, userInfo))
                        {
                            list.Add(userInfo);
                        }
                    }
                }
            }
            return list;
        }

        public static string GetFullNameByID(string userId)
        {
            string result = "";
            if (!string.IsNullOrEmpty(userId))
            {
                MethodBase currentMethod = MethodBase.GetCurrentMethod();
                result = MemoryCacheHelper.GetCacheItem($"{currentMethod.DeclaringType.FullName}-{currentMethod.Name}-{userId}", () => AsyncContext.Run(async () => await BLLFactory<IUserService>.Instance.GetFullNameByID(userId.ToInt32())) ?? "", new TimeSpan(0, 30, 0));
            }
            return result;
        }

        public static string GetOuName(int outId)
        {
            string result = "";
            if (outId > 0)
            {
                MethodBase currentMethod = MethodBase.GetCurrentMethod();
                result = MemoryCacheHelper.GetCacheItem($"{currentMethod.DeclaringType.FullName}-{currentMethod.Name}-{outId}", () => AsyncContext.Run(async () => await BLLFactory<IOuService>.Instance.GetName(outId)), new TimeSpan(0, 30, 0));
            }
            return result;
        }

        public static string GetMenuName(string menuId)
        {
            string result = "";
            if (!menuId.IsNullOrEmpty())
            {
                if (menuId == "-1")
                {
                    result = "顶级目录";
                }
                else
                {
                    MethodBase currentMethod = MethodBase.GetCurrentMethod();
                    result = MemoryCacheHelper.GetCacheItem($"{currentMethod.DeclaringType.FullName}-{currentMethod.Name}-{menuId}", () => AsyncContext.Run(async () => await BLLFactory<IMenuService>.Instance.GetName(menuId)), new TimeSpan(0, 30, 0));
                }
            }
            return result;
        }

        public static async Task<List<RoleInfo>> GetRoleList(int userId)
        {
            List<RoleInfo> result = new List<RoleInfo>();
            if (userId > 0)
            {
                MethodBase currentMethod = MethodBase.GetCurrentMethod();
                result = await MemoryCacheHelper.GetCacheItem($"{currentMethod.DeclaringType.FullName}-{currentMethod.Name}-{userId}", async () => await BLLFactory<IRoleService>.Instance.GetRolesByUser(userId), new TimeSpan(0, 30, 0));
            }
            return result;
        }

        public static async Task<List<OuInfo>> GetMyTopGroup(UserInfo userInfo)
        {
            var list = new List<OuInfo>();
            return await MemoryCacheHelper.GetCacheItem("Security_MyTopGroup" + userInfo.Id, async delegate
            {
                if (await UserInRole("超级管理员", userInfo.Id))
                {
                    List<OuInfo> collection = await BLLFactory<IOuService>.Instance.GetTopGroup();
                    list.AddRange(collection);
                }
                else
                {
                    OuInfo item = await BLLFactory<IOuService>.Instance.GetAsync(userInfo.Company_ID.ToInt32());
                    list.Add(item);
                }
                return list;
            }, new TimeSpan(0, 30, 0));
        }

        public static async Task<List<OuInfo>> GetMyGroupCompanyTree(UserInfo userInfo)
        {
            List<OuInfo> list = new List<OuInfo>();
            foreach (OuInfo item in await GetMyTopGroup(userInfo))
            {

                list.Add(item);
                if (item.Category == "集团")
                {
                    ListResultDto<OuInfo> listResultDto = await BLLFactory<IOuService>.Instance.GetAllAsync((OuInfo s) => s.Category == "公司" && s.PID == (int?)item.Id);
                    item.Children.Clear();
                    item.Children.AddRange(listResultDto.Items);
                }
            }
            return list;
        }

        public static async Task<List<OuInfo>> GetMyDeptTree(UserInfo userInfo)
        {
            List<OuInfo> list = new List<OuInfo>();
            int? pID = (await GetMyTopGroup(userInfo)).First().PID;
            if (pID.HasValue)
            {
                list = await BLLFactory<IOuService>.Instance.GetTreeByID(pID.Value);
            }
            return list;
        }

        public static async Task<List<OuInfo>> GetMyGroupCompany(UserInfo userInfo)
        {
            List<OuInfo> list = new List<OuInfo>();
            if (await UserInRole("超级管理员", userInfo.Id))
            {
                list = await BLLFactory<IOuService>.Instance.GetGroupCompany();
            }
            else
            {
                OuInfo ouInfo = await BLLFactory<IOuService>.Instance.GetAsync(userInfo.Company_ID.ToInt32());
                if (ouInfo != null)
                {
                    list.Add(ouInfo);
                }
            }
            return list;
        }

        public static async Task<bool> UserInRole(string roleName, int userId)
        {
            List<RoleInfo> list = await GetRoleList(userId);
            bool result = false;
            if (list != null)
            {
                foreach (RoleInfo item in list)
                {
                    if (item.Name.Equals(roleName, StringComparison.OrdinalIgnoreCase))
                    {
                        result = true;
                        break;
                    }
                }
            }
            return result;
        }
    }
}
